home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 6
/
CU Amiga Magazine's Super CD-ROM 06 (1996)(EMAP Images)(GB)(Track 1 of 4)[!][issue 1997-01].iso
/
cucd
/
online
/
fidonetts
/
3csrc.lzh
/
3mailin.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-02
|
15KB
|
503 lines
/* 3mailin.c
* Public Domain
*
* contains functions to read a type 3 ASCII packet
*
* code as presented is memory thrifty. if you've got plenty of memory,
* here are some performance suggestions:
*
* instead of reading headers a line at a time, read into a
* big buffer and parse in memory (32K guarantees getting full
* header under "worst" conditions). use same buffer used for
* message text to (normally) prevent reloading message to get
* text.
*
* and/or
*
* dynamically adjust size of msg text buffer based on average
* size (or most common size) of msgs received to date.
*
*
* user-callable function:
*
* long process_3pkt (void *anon, char *fname, int *error);
*
* anon = private data for "callback" functions
* fname = name of packet to process
* error = returned error code
* returns number of messages processed
*
* see comments @ function (end of file)
*/
#include "3mail.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
int open_3pkt (int i3handle,char *fname, int *error) {
/* open a type 3 packet for input
* i3handle = file handle in use (or -1 if none)
* fname = name of packet to open
* *error = error return code
*/
if(i3handle != -1) close(i3handle); /* close if already open */
i3handle = sopen(fname,O_RDONLY | O_BINARY,SH_DENYNO);
if(i3handle == -1) *error = NOOPEN3;
return i3handle;
}
int close_3pkt (int i3handle) { /* close a packet */
if(i3handle != -1) close(i3handle); /* close if good handle */
i3handle = -1; /* in case you made it global... */
return i3handle;
}
PHDR3 * free_3pkthdr (PHDR3 *cpkt) {
/* free dynamically allocated memory of a packet header structure
* including linked list of TAG3 structures attached, if any
*/
TAG3 *info,*next;
if(cpkt->from) free(cpkt->from);
if(cpkt->to) free(cpkt->to);
if(cpkt->creator) free(cpkt->creator);
if(cpkt->pword) free(cpkt->pword);
if(cpkt->area) free(cpkt->area);
if(cpkt->head) {
info = cpkt->head;
while(info) {
next = info->next;
if(info->tag) free(info->tag);
if(info->data) free(info->data);
free(info);
info = next;
}
}
free(cpkt);
cpkt = NULL;
return cpkt;
}
MHDR3 * free_3msghdr (MHDR3 *cmsg) {
/* free dynamically allocated memory of a message header structure
* including linked list of TAG3 structures attached, if any
*/
TAG3 *info,*next;
if(cmsg->from) free(cmsg->from);
if(cmsg->to) free(cmsg->to);
if(cmsg->subj) free(cmsg->subj);
if(cmsg->date) free(cmsg->date);
if(cmsg->area) free(cmsg->area);
if(cmsg->id) free(cmsg->id);
if(cmsg->ref) free(cmsg->ref);
if(cmsg->head) {
info = cmsg->head;
while(info) {
next = info->next;
if(info->tag) free(info->tag);
if(info->data) free(info->data);
free(info);
info = next;
}
}
free(cmsg);
cmsg = NULL;
return cmsg;
}
PHDR3 * create_3pkthdr (void) {
/* create an empty PHDR3 pkt header structure
* returns a pointer to the PHDR3 structure created
*/
PHDR3 *info;
info = (PHDR3 *)malloc(sizeof(PHDR3));
if(info) {
info->from = info->to = info->creator = info->pword = info->area = NULL;
info->head = NULL;
}
return info;
}
MHDR3 * create_3msghdr (void) {
/* create an empty MHDR3 msg header structure
* returns a pointer to the MHDR3 structure created
*/
MHDR3 * info;
info = (MHDR3 *)malloc(sizeof(MHDR3));
if(info) {
info->from = info->to = info->subj = info->date = info->id =
info->ref = info->area = NULL;
info->head = NULL;
}
return info;
}
PHDR3 * read_3pkthdr (int i3handle, PHDR3 *cpkt, int *error) {
/* could use more error & grunge checking
* returns NULL on error OR EOP
* *error may contain more info
* fills in cpkt from file represented by i3handle
*/
char s[257];
*error = NOTPKT3;
if(cpkt) free_3pkthdr(cpkt);
if(fgets3(s,256,i3handle)) {
if(!strcmp(s,ASCII3ID)) {
*error = BADPKTHDR3;
cpkt = create_3pkthdr();
if(cpkt) {
if(fgets3(s,256,i3handle)) {
cpkt->from = strdup3(s);
if(fgets3(s,256,i3handle)) {
cpkt->to = strdup3(s);
if(fgets3(s,256,i3handle)) {
cpkt->creator = strdup3(s);
if(cpkt->creator) {
if(fgets3(s,256,i3handle)) {
cpkt->pword = strdup3(s);
if(fgets3(s,256,i3handle)) {
cpkt->area = strdup3(s);
if(!(!cpkt->area && !cpkt->to)) {
while(!eof(i3handle)) {
char *data;
TAG3 *info;
TAG3 *here = cpkt->head;
if(!fgets3(s,256,i3handle)) break;
if(!*s) break; /* end of packet header */
data = strchr(s,' ');
if(data) {
*data = 0;
data++;
while(*data == ' ' || *data == '\t') data++;
}
/* code dealing with experimental tags goes here */
if(!strnicmp(s,"X-",2)) continue; /* then "strip"
* unrecognized
* experimental
* tags */
info = (TAG3 *)malloc(sizeof(TAG3));
if(!info) break; /* tsk, tsk */
info->tag = strdup3(s);
if(!info->tag) {
free(info);
break;
}
info->data = strdup3(data);
if(!cpkt->head) cpkt->head = info;
else here->next = info;
info->next = NULL;
here = info;
}
*error = NOERR3;
return cpkt; /* success */
}
}
}
}
}
}
}
}
else *error = NOMEM3;
}
}
if(cpkt) cpkt = free_3pkthdr(cpkt); /* failure */
return cpkt;
}
long find_next_3msg (int i3handle,int *error) {
/* find the next message in a packet (used when a grunged header is
* encountered to attempt to resynch
* just searches for a NUL in the file
*/
char *buf,*p;
int len;
long pos;
buf = (char *)malloc(BLKSIZE3);
if(!buf) {
*error = NOMEM3;
return -1L;
}
while(!eof(i3handle)) {
pos = tell(i3handle);
len = read(i3handle,buf,BLKSIZE3);
if(len == -1) {
*error = READERR3;
free(buf);
return -1L;
}
if(!len) break;
p = buf;
while(p < buf + len) {
if(!*p) {
p++;
lseek (i3handle, pos + ((int)p - (int)buf), SEEK_SET);
free(buf);
return tell(i3handle);
}
p++;
}
}
*error = EOP3;
free(buf);
return -1L;
}
MHDR3 * read_3msghdr (int i3handle, MHDR3 *cmsg, int *error) {
/* could use more error & grunge checking
* return NULL on error OR EOP
* *error may contain more info
* fills in msg header structure cmsg from file represented
* by file handle i3handle
*/
char s[257];
int tries = 0;
ReTry:
*error = EOP3;
if(cmsg) free_3msghdr(cmsg);
if(fgets3(s,256,i3handle) && *s) {
cmsg = create_3msghdr();
if(cmsg) {
*error = BADMSGHDR3;
cmsg->from = strdup3(s);
if(cmsg->from) {
if(fgets3(s,256,i3handle)) {
cmsg->to = strdup3(s);
if(fgets3(s,256,i3handle)) {
cmsg->subj = strdup3(s);
if(fgets3(s,256,i3handle)) {
cmsg->date = strdup3(s);
if(cmsg->date) {
if(fgets3(s,256,i3handle)) {
cmsg->area = strdup3(s);
if(fgets3(s,256,i3handle)) {
cmsg->id = strdup3(s);
if(cmsg->id) {
if(fgets3(s,256,i3handle)) {
cmsg->ref = strdup3(s);
while(!eof(i3handle)) {
char *data = NULL;
TAG3 *info;
TAG3 *here = cmsg->head;
if(!fgets3(s,256,i3handle)) break;
if(!*s) break; /* end of message header */
data = strchr(s,' ');
if(data) {
*data = 0;
data++;
while(*data == ' ' || *data == '\t') data++;
}
/* code dealing with experimental tags goes here */
if(!strnicmp(s,"X-",2)) continue; /* then "strip"
* unrecognized
* experimental
* tags */
info = (TAG3 *)malloc(sizeof(TAG3));
if(!info) break; /* tsk, tsk */
info->tag = strdup3(s);
if(!info->tag) {
free(info);
break;
}
info->data = strdup3(data);
if(!cmsg->head) cmsg->head = info;
else here->next = info;
info->next = NULL;
here = info;
}
*error = NOERR3;
return cmsg; /* success */
}
}
}
}
}
}
}
}
}
if(find_next_3msg(i3handle,error) != -1L && tries++ < MAXRESYNC3)
goto ReTry; /* skip to next msg -- goto? suffer!!! */
}
else *error = NOMEM3;
}
if(cmsg) cmsg = free_3msghdr(cmsg);
return cmsg;
}
int read_3msgtext (int i3handle,char *msg, int buflen, int *error) {
/* call until 0 or -1 is returned. 0 = EOM -1 = EOP
* i3handle is file handle for packet
* msg = text buffer
* buflen = length of buffer
*/
int bufread = 0;
long sizefile,pos;
char *p;
*error = NOERR3;
if(!eof(i3handle)) {
sizefile = filelength(i3handle);
pos = tell(i3handle);
if(sizefile > pos)
bufread = read(i3handle,msg,min(buflen,(int)(sizefile - pos)));
if(bufread > 0) {
p = strchr(msg,'\0'); /* EOM marker */
if(p) {
p++;
bufread = (int)p - (int)msg;
lseek(i3handle,pos + (long)bufread,SEEK_SET); /* pos to start of next msg */
}
}
else if(bufread == -1) *error = READERR3;
}
return bufread;
}
long process_3pkt (void *anon,char *fname,int *error) {
/* process a type 3ASCII packet. four functions are external ("callback"):
*
* int import_3msg(void *anon,PHDR3 *,MHDR3 *,char *text,
* int length,int *error);
* int appendin_3msg(void *anon,PHDR3 *,MHDR3 *,char *text,
* int length,int *error);
*
* these functions should handle import to the message base and
* export to outgoing packets as required by the bbs/mailer, as
* well as dupe checking on the message header id field. return
* non-zero to abort processing of packet.
*
* int check_3pkthdr(void *anon,char *fname,PHDR3 *,int *error);
*
* this function should return 0 if the packet should be processed,
* or anything else to abort processing and return control to caller.
*
* int check_3msghdr(void *anon,MHDR3 *,int *error);
*
* this function should return 0 if the message should be processed,
* or anything else to skip it and go for the next message.
*
* anon = private data for "callback" functions
* fname = name of packet to process
* *error = returned error code
* returns number of msgs processed
*/
PHDR3 *cpkt = NULL;
MHDR3 *cmsg = NULL;
char *msgtext;
int textlen;
int i3handle = -1;
long nummsgs = 0;
*error = NOERR3;
msgtext = (char *)malloc(BLKSIZE3 + 1);
if(msgtext) {
i3handle = open_3pkt(i3handle,fname,error);
if(i3handle != -1) {
cpkt = read_3pkthdr(i3handle,cpkt,error);
if(cpkt) {
if(!check_3pkthdr(anon,fname,cpkt,error)) {
do {
cmsg = read_3msghdr(i3handle,cmsg,error);
if(*error) break;
if(cmsg) {
textlen = read_3msgtext(i3handle,msgtext,BLKSIZE3,error);
if(*error) break;
if(check_3msghdr(anon,cmsg,error)) {
*error = NOERR3;
if(find_next_3msg(i3handle,error) == -1L) break;
continue;
}
if(textlen > 0) {
nummsgs++;
if(import_3msg(anon,cpkt,cmsg,msgtext,textlen,error)) break;
while(textlen == BLKSIZE3) {
textlen = read_3msgtext(i3handle,msgtext,BLKSIZE3,error);
if(*error) break;
if(textlen > 0) {
if(appendin_3msg(anon,cpkt,cmsg,msgtext,textlen,error)) break;
}
}
#ifdef TRANSLATING
end_3msg(anon,cpkt,cmsg);
#endif
}
}
} while(cmsg);
}
}
i3handle = close_3pkt(i3handle);
}
}
else *error = NOMEM3;
if(cpkt) free_3pkthdr(cpkt);
if(cmsg) free_3msghdr(cmsg);
if(msgtext) free(msgtext);
return nummsgs;
}